/*
* MIT License
*
* Copyright (c) 2017 wen.gu <454727014@qq.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/***************************************************************************
* Name: tiny_ring_buffer.h
*
* Purpose: ring buffer implementation
*
* Developer:
*   wen.gu , 2018-08-07
*
* TODO:
*
***************************************************************************/
#ifndef __TINY_RING_BUFFER_H__
#define __TINY_RING_BUFFER_H__

#include "general_type.h"

#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************
*
* macro declaration
*
***************************************************************************/

/***************************************************************************
*
* data structure declaration
*
***************************************************************************/

/** ring buffer data structure define */
typedef struct tiny_ring_buffer_s
{
    GS32 last_error; /** recording last operation errror code */
    GU32 size;       /** ring buffer total size */
    GU08 *data;      /** ring buffer base address */
}tiny_ring_buffer_t;


/***************************************************************************
*
* API declaration
*
***************************************************************************/

/*
*@brief create ring buffer instance
*
*@param trb  [out] ring buffer API instance pointer
*@param size [in]  the request ring buffer size
*@param data [in]  extern supply the memory pointer, if put as NULL, the
*                  tiny ring buffer will auto allocate memory with input
*                  'size'
*
*@return none.
*
**/
G_API GS32 tfRingBufferCreate(tiny_ring_buffer_t** trb, GU32 size, void* data);

/*
*@brief destroy ring buffer instance.
*
*@param trb  [in] ring buffer API pointer
*
*@return none.
*
**/
G_API void tfRingBufferDestroy(tiny_ring_buffer_t* trb);


/*
*@brief reset ring buffer to initial state
*
*@param trb  [in] ring buffer API pointer
*
*@return none.
*
**/
G_API void tfRingBufferReset(tiny_ring_buffer_t* trb);

/*
*@brief get how may bytes data cached in ring buffer
*
*@param trb  [in] ring buffer API pointer
*
*@return the size of cached data in ring buffer.
*
**/
G_API GU32 tfRingBufferGetCachedSize(tiny_ring_buffer_t* trb);

/*
*@brief get free space in ring buffer
*
*@param trb  [in] ring buffer API pointer
*
*@return the size of free space in ring buffer.
*
**/
G_API GU32 tfRingBufferGetFreeSpace(tiny_ring_buffer_t* trb);

/*
*@brief request/allocate memory
*
*@param trb  [in] ring buffer API pointer
*@param size [in] requested memory size
*
*@return success: memory pointer, failed: NULL.
*
*@note  when return NULL, user can get error code by
*       tiny_ring_buffer_s.last_error
*
**/
G_API void*  tfRingBufferAlloc(tiny_ring_buffer_t* trb, GU32 size);

/*
*@brief reallocate memory
*
*@param trb      [in] ring buffer API pointer
*@param new_size [in] reallocated memory size
*@param old_ptr  [in] old memory pointer
*@param old_size [in] the size of old memory
*
*@return success: memory pointer, failed: NULL.
*
*@note  1. when return NULL, user can get error code by
*          tiny_ring_buffer_s.last_error
*      
*       2. if need change the size of buffer with this API, then
*          we can only change current alloced buffer, because 
*          the alloc and release operation is rules with FIFO,
*          we can't change the size of buffer which not current 
*          alloced buffer.
*
**/

G_API void*  tfRingBufferRealloc(tiny_ring_buffer_t* trb, GU32 new_size, void* old_ptr, GU32 old_size);

/*
*@brief  free one segment memory
*
*@param trb  [in] ring buffer API pointer
*@param ptr  [in] memory pointer
*@param size [in] the size of memory
*
*@return none.
*
**/
G_API void tfRingBufferFree(tiny_ring_buffer_t* trb, void* ptr, GU32 size);

/*
*@brief print the information of read ptr, write ptr and so on.
*
*@param trb  [in] ring buffer API pointer
*
*@return none.
*
**/
G_API void tfRingBufferDump(tiny_ring_buffer_t* trb);



#ifdef __cplusplus
}
#endif

#endif /** !__TINY_RING_BUFFER_H__*/